package com.hivekion.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hivekion.common.core.SystemConstant;
import com.hivekion.common.entity.PagedResultVo;
import com.hivekion.common.entity.SelectOption;
import com.hivekion.common.redis.RedisUtil;
import com.hivekion.system.domain.SysDictData;
import com.hivekion.system.domain.vo.dict.*;
import com.hivekion.system.mapper.SysDictDataMapper;
import com.hivekion.system.service.ISysDictDataService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysDictDataService extends ServiceImpl<SysDictDataMapper, SysDictData>
        implements ISysDictDataService {
    @Autowired
    private RedisUtil redisUtil;

    @Override
    public boolean add(SysDictDataCreateVo createVo) {
        SysDictData data = new SysDictData();
        BeanUtils.copyProperties(createVo, data);
        return this.save(data);
    }

    @Override
    public boolean edit(SysDictDataUpdateVo updateVo) {
        SysDictData data = this.getById(updateVo.getId());
        BeanUtils.copyProperties(updateVo, data);
        return this.save(data);
    }

    @Override
    public boolean remove(String key) {
        return this.removeById(key);
    }

    @Override
    public SysDictDataModelVo get(String key) {
        SysDictData data = this.getById(key);
        SysDictDataModelVo vo = new SysDictDataModelVo();
        BeanUtils.copyProperties(data, vo);
        return vo;
    }

    @Override
    public PagedResultVo<SysDictDataViewVo> getList(SysDictDataSearchPageInputVo inputVo) {
        LambdaQueryWrapper<SysDictData> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SysDictData::getDictCode, inputVo.getDictCode());
        queryWrapper.and(
                StringUtils.isNotEmpty(inputVo.getFilter()),
                t ->
                        t.like(SysDictData::getDictLabel, inputVo.getFilter())
                                .or()
                                .like(SysDictData::getDictValue, inputVo.getFilter()));
        Page<SysDictData> dataPage = new Page<>(inputVo.getPageNum(), inputVo.getPageSize());
        dataPage.addOrder(new OrderItem("sort_code", true));
        IPage<SysDictData> data = this.page(dataPage, queryWrapper);
        List<SysDictDataViewVo> list =
                data.getRecords().stream()
                        .map(
                                t -> {
                                    SysDictDataViewVo vo = new SysDictDataViewVo();
                                    BeanUtils.copyProperties(t, vo);
                                    return vo;
                                })
                        .collect(Collectors.toList());
        PagedResultVo<SysDictDataViewVo> resultVo =
                new PagedResultVo<SysDictDataViewVo>(inputVo, (int) data.getTotal(), list);
        return resultVo;
    }

    @Override
    public List<SelectOption> getOptions(String dictType) {
        LambdaQueryWrapper<SysDictData> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SysDictData::getDictCode, dictType);
        List<SysDictData> list = this.list(queryWrapper);
        List<SelectOption> data =
                list.stream()
                        .sorted(Comparator.comparing(SysDictData::getSortCode))
                        .map(
                                item -> {
                                    SelectOption option = new SelectOption();
                                    option.setTitle(item.getDictLabel());
                                    option.setValue(item.getId());
                                    option.setKey(item.getId());
                                    option.setDisabled(item.getStatus() != 0);
                                    return option;
                                })
                        .collect(Collectors.toList());
        return data;
    }

    @Override
    public List<SysDictData> getAllData() {
        if (redisUtil.hasKey(SystemConstant.redis_dict_data)) {
            List<SysDictData> list =
                    JSON.parseArray(
                            redisUtil.get(SystemConstant.redis_dict_data).toString(),
                            SysDictData.class);
            return list;
        } else {
            List<SysDictData> dataList = this.list(null);
            redisUtil.set(SystemConstant.redis_dict_data, JSON.toJSONString(dataList));
            return dataList;
        }
    }
}
